﻿#include "QtRunLog.h"

#include <QFile>
#include <QMutex>
#include <QDateTime>
#include <qdebug.h>
#include <QDir>
#include <iostream>

//#include "DataStruct.h"
//#include "StdoutRedirector/stdoutredirector.h"

QString RunLogPath("");

QtRunLog::QtRunLog(QWidget *parent)
	: QWidget(parent)
{
#ifdef ENABLEREDIRECTOR
	redirector = new StdoutRedirector(this, StdoutRedirector::StandardOutput | StdoutRedirector::StandardError);
	connect(redirector, SIGNAL(readyRead()), this, SLOT(readData()));
#endif
	//pBuf << stdout;
	ui.setupUi(this);

    QString FileName(RunLogPath+QString("/%1%2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")).arg("_log.txt"));
	pLogFile = new QFile(FileName);
}

QtRunLog::~QtRunLog()
{
#ifdef ENABLEREDIRECTOR
	if (redirector != nullptr)
		delete redirector;
#endif

	if (pLogFile != nullptr)
		delete pLogFile;
}

//显示日志
void QtRunLog::LogMessageWindowSlot(const QtMsgType type, const QString current_date_time, const QString &msg)
{
	static QMutex WindowMutex;
	//注意这里，使用QMutexLocker
	QMutexLocker locker(&WindowMutex);

	ui.LogTableWidget->insertRow(0);
	QTableWidgetItem *LogCol0 = nullptr;
	QTableWidgetItem *LogCol1 = new QTableWidgetItem(current_date_time);
	QTableWidgetItem *LogCol2 = new QTableWidgetItem(msg);

	switch (type)
	{
	case QtInfoMsg:
		LogCol0 = new QTableWidgetItem("Info");
		LogCol0->setBackgroundColor(QColor(Qt::lightGray));
		LogCol1->setBackgroundColor(QColor(Qt::lightGray));
		LogCol2->setBackgroundColor(QColor(Qt::lightGray));
		break;
	case QtDebugMsg:
		LogCol0 = new QTableWidgetItem("Debug");
		LogCol0->setBackgroundColor(QColor(Qt::gray));
		LogCol1->setBackgroundColor(QColor(Qt::gray));
		LogCol2->setBackgroundColor(QColor(Qt::gray));
		break;

	case QtWarningMsg:
		LogCol0 = new QTableWidgetItem("Warning");
		LogCol0->setBackgroundColor(QColor(Qt::magenta));
		LogCol1->setBackgroundColor(QColor(Qt::magenta));
		LogCol2->setBackgroundColor(QColor(Qt::magenta));
		break;

	case QtCriticalMsg:
		LogCol0 = new QTableWidgetItem("Critical");
		LogCol0->setBackgroundColor(QColor(Qt::darkRed));
		LogCol1->setBackgroundColor(QColor(Qt::darkRed));
		LogCol2->setBackgroundColor(QColor(Qt::darkRed));
		break;

	case QtFatalMsg:
		LogCol0 = new QTableWidgetItem("Fatal");
		LogCol0->setBackgroundColor(QColor(Qt::red));
		LogCol1->setBackgroundColor(QColor(Qt::red));
		LogCol2->setBackgroundColor(QColor(Qt::red));
		break;

	default:
		LogCol0 = new QTableWidgetItem("Debug");
		LogCol0->setBackgroundColor(QColor(Qt::gray));
		LogCol1->setBackgroundColor(QColor(Qt::gray));
		LogCol2->setBackgroundColor(QColor(Qt::gray));
		break;
	}

	ui.LogTableWidget->setItem(0, 0, LogCol0);
	ui.LogTableWidget->setItem(0, 1, LogCol1);
	ui.LogTableWidget->setItem(0, 2, LogCol2);

	if (ui.LogTableWidget->rowCount() > 60)
	{
		ui.LogTableWidget->removeRow(ui.LogTableWidget->rowCount()-1);
	}
}

static QMutex FileMutex;

void QtRunLog::LogMessageToFileSlot(const QtMsgType type, const QString current_date_time, const QString &msg)
{
	//注意这里，使用QMutexLocker
	QMutexLocker locker( &FileMutex );

	QString text;
	bool flag = true;
	switch (type)
	{
	case QtDebugMsg://qDebug
		//flag = false;
		text = QString("; Debug; ");
		break;
	case QtInfoMsg://qInfo
		text = QString("; Info;");
		break;
	case QtWarningMsg://qWarning
		text = QString("; Warning;");
		break;
	case QtCriticalMsg://qCritical
		text = QString("; Critical;");
		break;
	case QtFatalMsg://qFatal
		text = QString("; Fatal;");
		goto abortPoint;
		//abort();
	default:
		text = QString("; Unknow;");
	}

	if (flag)
	{
		QString message = QString("[%1] %2 %3").arg(current_date_time).arg(text).arg(msg);
		//QFile file(QString("Log/%1%2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")).arg("_log.txt"));
		//QFile file(QString("log.txt"));
		pLogFile->open(QIODevice::WriteOnly | QIODevice::Append);
		QTextStream text_stream(pLogFile);
		text_stream << message << endl;
		//pLogFile->flush();
		pLogFile->close();
	}
	return ;

abortPoint:
	if (flag)
	{
		QString message = QString("[%1] %2 %3").arg(current_date_time).arg(text).arg(msg);
		//QFile file(QString("Log/%1%2").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")).arg("_log.txt"));
		//QFile file(QString("log.txt"));
		pLogFile->open(QIODevice::WriteOnly | QIODevice::Append);
		QTextStream text_stream(pLogFile);
		text_stream << message << endl;
		//pLogFile->flush();
		pLogFile->close();
	}

	abort();
}

void QtRunLog::readData()
{
#ifdef ENABLEREDIRECTOR
	qInfo() << "stdout" << ":" <<redirector->read(redirector->bytesAvailable());
#endif
}

const int mounth_days[12] =
/*  1   2   3   4   5   6   7   8   9  10  11  12*/
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//此处定义每月的天数

												   /*将对应的日期换算成天数，因此1月是0天，2月是31天，3月是0+21+28天以此类推
												   在下面会为数组填充数据*/
int mounth_days_add[12];

//删除days之前的的日志
bool QtRunLog::DeleteOldFile(const QString dirPath, const QStringList suffix, const uint days)
{
	QDir dir(dirPath);//程序当前目录，qt下该目录取决于构建时的debug存放地址
	if (!dir.exists())
	{
		return false;
	}

	if (suffix.isEmpty())
	{
		return false;
	}

	QStringList filters(suffix);//设置过滤器
	//filters << "*_log.txt";//过滤留下txt文件
	dir.setNameFilters(filters);

	QDateTime curDate = QDateTime::currentDateTime();//获取当前时间
	QFileInfoList infoList = dir.entryInfoList();
	qint64 DaysSecs = days * 24 * 60 * 60;

	//循环遍历，在Qlist中存取文件名
	foreach(QFileInfo mItem, infoList)
	{
        QString FileFullPath = mItem.absoluteFilePath();
		if ( QFile::exists(FileFullPath) )
		{
			//--获取文件创建时间
			QDateTime buildTime = mItem.created();
			
			qint64 dSecs = curDate.toSecsSinceEpoch() - buildTime.toSecsSinceEpoch();
			if (dSecs > DaysSecs)  //判断文件的创建时间
			{
				if (QFile::remove(FileFullPath))
				{
					qDebug() << QObject::tr(u8"删除文件:") << mItem.fileName() << buildTime.toString();
				}
			}
			else
			{
				qDebug() << mItem.fileName() << QObject::tr(u8" 创建时间:") << buildTime.toString();
			}
		}
	}

	return true;
}
